package com.gopay.bis.service.bank.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.SendSmsUtils;
import com.gopay.bis.manager.bank.BankOrderManager;
import com.gopay.bis.manager.bank.payconfig.BisBankExtConfigManager;
import com.gopay.bis.service.bank.BankIntrChannConfService;
import com.gopay.bis.service.bank.BankIntrChannConfService.OutStlmTranCode;
import com.gopay.bis.service.bank.BankOrderService;
import com.gopay.bis.service.bank.go.GoBankService;
import com.gopay.bis.service.bank.query.BisBankWhiteListMerchantsService;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.BankOrderType;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BankOrderExt;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.MerchantModelInfo;
import com.gopay.common.domain.bank.MicroPayBaseMessage;
import com.gopay.common.domain.bank.MicroPayRequest;
import com.gopay.common.domain.bis.BaseBisBankConfig;
import com.gopay.common.domain.bis.BaseBisBankExtConfig;
import com.gopay.common.domain.bis.BisMicroPayConfig;
import com.gopay.common.domain.bis.RouteMessage;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.proccode.ProcCodeInfo;
import com.gopay.common.exception.GopayException;
import com.gopay.common.order.bankorder.trade.InitialSpringBeanName;
import com.gopay.common.order.bankorder.trade.TradeType;
import com.gopay.common.proccode.DicProcCodeService;
import com.gopay.common.util.HttpTransport;
import com.gopay.common.util.RSAEncoderUtil;
import com.gopay.common.util.spring.SpringContextUtil;
import com.gopay.remote.bank.MicroPayInteractRemoteService;
import com.gopay.remote.bank.autoroute.BankRoute;
import com.gopay.remote.cashier.bis.CashierBgNotifyRemoteService;

/**
 * 小额免密支付业务实现
 * 
 * @ClassName: MicroPayInteractServiceImpl
 * @author w_jiqing
 * @date 2017年5月26日 下午2:47:17
 */
@Service("microPayInteractService")
public class MicroPayInteractServiceImpl implements MicroPayInteractRemoteService {

    /**
     * 定义日志对象
     */
    private static Logger logger = LoggerFactory.getLogger(MicroPayInteractServiceImpl.class);
    private static final String AUTO_ROUTING = "on"; // 银行自动路由开关

    @Resource(name = "goBankService")
    private GoBankService goBankService;

    @Resource(name = "smsConfig")
    private Map<String, String> smsConfig;

    @Resource(name = "bankIntrChannConfService")
    private BankIntrChannConfService bankIntrChannConfService;

    @Resource(name = "cpsGeneralMainOrderQueryManager")
    private CpsGeneralMainOrderQueryManager mainOrderQuery;

    @Resource(name = "bankOrderService")
    private BankOrderService bankOrderService;

    @Resource(name = "dicProcCodeService")
    private DicProcCodeService dicProcCodeService;

    @Resource(name = "bisBankExtConfigManager")
    BisBankExtConfigManager bisBankExtConfigManager;

    @Resource(name = "bankOrderManager")
    private BankOrderManager bankOrderManager;

    @Resource(name = "bisConfig")
    private Map<String, String> bisConfig;

    @Resource(name = "notifyCashier")
    private HttpTransport notifyCashier;

    @Resource(name = "cashierBgNotifyRemoteService")
    private CashierBgNotifyRemoteService cashierBgNotifyRemoteService;

    @Resource(name = "bankRouteService")
    private BankRoute bankRouteService;

    @Resource(name = "normalBankRouteService")
    private BankRoute normalBankRouteService;

    @Resource(name = "bisBankWhiteListMerchantsService")
    private BisBankWhiteListMerchantsService bisBankWhiteListMerchantsService;

    @Override
    public Result pay(BaseMessage msg) throws GopayException {
        logger.info("------------MicroPayInteractServiceImpl pay start-------------");
        long beginTime = System.currentTimeMillis();
        /**
         * 打印请求参数
         */
        MicroPayRequest request = (MicroPayRequest) msg;

        logger.error("收到的请求参数键:" + ToStringBuilder.reflectionToString(request));
        Result result = new Result();
        BisMicroPayConfig bisScanConfig=null;
        try {
            /**
             * 基础参数校验
             */
            checkRequest(request);

            /**
             * 构建消息对象
             */
            BaseMessage base = goBankService.buildSign(request.getOrderId(), request.getMchCreateIp());
            BisBankBusinessProd bankBusProdEnum = BisBankBusinessProd.get(request.getBankBusProd().value);
            base.setBankBusProd(bankBusProdEnum);
            BaseBisBankExtConfig bankConfig = new BaseBisBankExtConfig();

            if (isRouteOrWhiteList(base.getSpecial2())) {
                // 增加银行自动路由开关 add by zhengxue
                RouteMessage routeMessage = new RouteMessage();
                routeMessage.setCustId(base.getSpecial2());
                routeMessage.setGopayOrderId(base.getOrderId());
                routeMessage.setBankCode(base.getBank());
                routeMessage.setProdCode(request.getBankBusProd().value);
                routeMessage.setTransAmt(base.getAmount());

                if (IntTxnCd._00500.value.equals(base.getSpecial4())
                        || BankConstants.GOPAY_CHONGZHI_CUSTID.equals(base.getSpecial2())) {
                    // 充值交易走通用方案
                    bankConfig = normalBankRouteService.getNormalRoute(routeMessage);
                    if (BankConstants.GOPAY_CHONGZHI_CUSTID.equals(base.getSpecial2())
                            && !IntTxnCd._00500.value.equals(base.getSpecial4())) {
                        // 非充值订单获取merId为GFB0000001
                        logger.error(
                                base.getOrderId() + " ScanPayInteractServiceImpl支付交易获取商户ID为: " + base.getSpecial2());
                    }
                } else {
                    bankConfig = bankRouteService.getRoute(routeMessage);
                }
                bankOrderService.addBankRouteLog(routeMessage); // 记录银行自动路由日志
            } else {
                /**
                 * 获取银行接口通道配置信息
                 */
                bankConfig = bankIntrChannConfService.findBaseBisBankExtConfig(base.getBankBusProd(), base.getBank());
            }

            if (BisBankInterfaceChannel._14.value.equals(bankConfig.getChCode())) {
                // 银行产品空通道
                logger.error(base.getOrderId() + " ScanPayInteractServiceImpl获取银行产品空通道");
                result.setResultCode(ProcCodeConstants.PROC_CODE_100E6090);
                result.setSuccess(false);
                return result;
            }

            /**
             * 校验银行业务产品是否支持该通道
             */
            checkBankBussProdAndIntrChan(bankConfig, request.getBankBusProd().value);
            /**
             * 校验通道信息
             */
            checkBankIntrChan(bankConfig, OutStlmTranCode._1000);
        	/**
			 * 判断银行接口通道是否支持一户一码，
			 * 判断是否上送当前渠道商户所配置的商户号和密钥
			 * 都支持替换商户号和密钥，否则走默认（国付宝商户）
			 */
			bisScanConfig=(BisMicroPayConfig)bankConfig;
			String merchantModel=bisScanConfig.getMerchantModel()==null?"":bisScanConfig.getMerchantModel();	
			if (bankConfig.getChCode().equals(BisBankInterfaceChannel._15.value) || bankConfig.getChCode().equals(BisBankInterfaceChannel._28.value)) {
			if(merchantModel.equals("1")){				
				/**
				 * 判断当前渠道是否支持一户一码
				 */
				List<MerchantModelInfo>merchantModelInfoList=request.getMerchantModel();
				logger.error("merchantModelInfoList=" + merchantModelInfoList);
				if(null!=merchantModelInfoList){
					for(MerchantModelInfo merchantModelInfo:merchantModelInfoList){
						if(bankConfig.getChCode().equals(merchantModelInfo.getChannelCode())){
							if(StringUtils.isNotBlank(merchantModelInfo.getIntrMernum())&&
									StringUtils.isNotBlank(merchantModelInfo.getIntrMerkey())){
								bankConfig.setIntrMernum1(merchantModelInfo.getIntrMernum());
								bankConfig.setIntrMerPravkeyPath(merchantModelInfo.getIntrMerkey());
								base.setMerchantModel(true);
							}				
						}
					}
				}
			}
			}

            /**
             * 平台外部清算机构代码 支付宝，微信
             */
            String outStlmCd = InitialSpringBeanName.getOutStlmCd(bankConfig.getChCode(),
                    request.getBankBusProd().value, base.getBank());
            /**
             * 上送银行code WECHAT ALIPAY
             */
            String intrfaceBankCode = bankConfig.getIntrfaceBankCode();
            if (StringUtils.isBlank(intrfaceBankCode)) {
                intrfaceBankCode = base.getBank();
            }
            base.setBankIntrChann(BisBankInterfaceChannel.get(bankConfig.getChCode()));
            base.setSpecial(request.getMchCreateIp());
            base.setOutStlmCd(outStlmCd);

            MicroPayBaseMessage microPayMsg = new MicroPayBaseMessage();
            /**
             * 设置扫码支付信息
             */
            BeanUtils.copyProperties(base, microPayMsg);
            microPayMsg.setDeviceInfo(request.getDeviceInfo());
            microPayMsg.setMchCreateIp(request.getMchCreateIp());
            microPayMsg.setGoodsBody(request.getGoodsBody());
            microPayMsg.setGoodsTag(request.getGoodsTag());
            microPayMsg.setAuthCode(request.getAuthCode());
            microPayMsg.setBankOrderId(modifyOrderId(microPayMsg.getOrderId(), bankConfig.getChCode()));

            /**
             * 获取订单信息与银行信息
             */
            CpsGenMainOrder mainOrder = mainOrderQuery.get(microPayMsg.getOrderId());
            microPayMsg.setCustomerID(mainOrder.getMainRecvCustId());
            /**
             * 获取SPRING加载的BeanName
             */
            String beanName = getBeanName(mainOrder, base.getOutStlmCd(), bankConfig.getChCode());
            MicroPayInteractRemoteService microPayService = (MicroPayInteractRemoteService) SpringContextUtil
                    .getBean(beanName);
            if (!BisPayCheckUtils.checkExternalOrderID(base.getOrderId())) {

                // 设置一级私钥路径
                microPayMsg.setPrivateKeyPath(bankConfig.getIntrMerPravkeyPath());
                // 设置一级私钥密码
                microPayMsg.setPrivatePwd(bankConfig.getIntrMerPravkeyPwd());
                // 设置二级私钥路径
                microPayMsg.setPrivateKeyPath2nd(bankConfig.getIntrMer2ndPravkeyPath());
                // 设置二级私钥密码
                microPayMsg.setPrivatePwd2nd(bankConfig.getIntrMer2ndPravkeyPwd());
                // 设置公钥路径
                microPayMsg.setPublicKeyPath(bankConfig.getIntrBankPubkeyPath());
                // 设置商户号
                microPayMsg.setMerID(bankConfig.getIntrMernum1());
                // 设置二级商户号
                microPayMsg.setMerID2nd(bankConfig.getIntrMernum2());
                // 设置结算账户网点联行号
                microPayMsg.setBranchCode(bankConfig.getBranchCode());
                // 设置银行支付地址
                microPayMsg.setPayUrl(bankConfig.getPayUrl());
                // 设置支付后台通知地址
                microPayMsg.setPayRuturnUrl(bankConfig.getPayRuturnUrl());
            }

            /**
             * 校验银行订单不能为多条,此处以后修改
             */
            List<BankOrder> bankOrders = bankOrderService.getBankOrdersByGopayOrderId(base.getOrderId());
            if (bankOrders != null && bankOrders.size() > 0) {
                result.setResultCode(ProcCodeConstants.PROC_CODE_100E5015);// 已存在相同的订单
                result.setSuccess(false);
                return result;
            }
            
            microPayMsg.setBankOrderType(BankOrderType.GOPAY_BIS_ORDER);// 订单类型：新平台订单
            logger.error("需要保存数据库base:" + ToStringBuilder.reflectionToString(microPayMsg));
            
            bankOrderService.addBankOrder(microPayMsg);
            
            /**
             * 调用支付方法
             */
            result = microPayService.pay(microPayMsg);

            logger.error("MicroPayInteractServiceImpl 小额免密支付请求返回处理对象：" + ToStringBuilder.reflectionToString(result));

            // 中信小额免密支付同步返回处理结果
            if (BisBankBusinessProd._25.value.equals(microPayMsg.getBankBusProd().value)) {
                dealOrderAfterPay(microPayMsg, result);
            }
        } catch (GopayException e) {
            logger.error("MicroPayInteractServiceImpl GopayException", e);
            ProcCodeInfo procCodeInfo = dicProcCodeService.getProcCodeInfo(e.getErrCode());
            result.setSuccess(false);
            result.setResultCode(e.getErrCode());
            result.setErrorMsg(procCodeInfo.getMessage());
        } catch (Exception e) {
            logger.error("MicroPayInteractServiceImpl Exception", e);
            result.setSuccess(false);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setErrorMsg(e.getMessage());
        }

        long endTime = System.currentTimeMillis();
        logger.info("------ MicroPayInteractServiceImpl pay end，耗时(ms):" + (endTime - beginTime));
        return result;
    }

    /**
     * 支付订单--同步处理操作
     * 
     * @param microPayMsg
     * @param result
     * @author w_jiqing
     */
    private void dealOrderAfterPay(MicroPayBaseMessage microPayMsg, Result result) throws GopayException{

        try {
            if (!result.isSuccess()) {// 处理失败
                logger.error("MicroPayInteractServiceImpl dealOrderAfterPay resultCode:" + result.getResultCode());
                return;
            }

            Map<String, String> param = new HashMap<String, String>();
            BankOrder bankOrder = null;
            bankOrder = bankOrderManager.getBankOrderById(microPayMsg.getBankOrderId());
            if (bankOrder == null) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041);
            }
            param = (Map<String, String>) result.getModel("isNotifyCashier");
            logger.error("MicroPayInteractServiceImpl pay resMsg: " + ToStringBuilder.reflectionToString(microPayMsg));
            if ((Boolean) result.getDefaultModel()) {
                if (result.isOrderStatus()) {
                    // 支付成功
                    String amt = (String) param.get("amt"); // 银行返回交易金额
                    if (bankOrder.getSendBankAmt() != null
                            && bankOrder.getSendBankAmt().compareTo(new BigDecimal(amt)) != 0) {
                        // 银行返回金额与平台上送金额不符
                        bankOrderManager.updateAmountError(param.get("orderId"));
                        logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 支付返回处理结果：国付宝订单号【"
                                + param.get("orderId") + "】金额比对异常");
                        SendSmsUtils.sendSmsErr(smsConfig.get("switch"), smsConfig.get("mobile"),
                                "注意!!!支付订单金额不一致,银行:" + microPayMsg.getOutStlmCd() + "orderId:" + param.get("orderId"));
                        return;
                    }
                    bankOrderManager.updateBackSuccess(param.get("orderId"));
                    logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 支付返回处理结果：国付宝订单号【"
                            + param.get("orderId") + "】支付成功，bis_bank_main_order表更新成功状态");

                    param.put("sign", signRes(param));
                    logger.error("bis pay notify cashier: " + param);
                    /*notifyCashier.submit(param);*/ //生产优化10期 lx 2017-9-30 16:23:37
                    cashierBgNotifyRemoteService.callBgNotify(param);
                } else if (result.isOrderFail()) {
                    // 订单明确返回支付失败
                    bankOrder.setOrderStatus(BankOrderStatus.ORDER_FAIL);
                    bankOrderManager.updateBankOrder(bankOrder);
                    logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 支付返回处理结果：国付宝订单号【"
                            + param.get("orderId") + "】支付失败");
                    param.put("sign", signRes(param));
                    logger.error("bis pay notify cashier: " + param);
                   /* notifyCashier.submit(param);*/ //生产优化10期 lx 2017-9-30 16:23:37
                    cashierBgNotifyRemoteService.callBgNotify(param);
                } else {
                    logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 支付返回处理结果：国付宝订单号【"
                            + microPayMsg.getOrderId() + "】验签成功订单支付未成功");
                }
            } else {
                bankOrderManager.updateBackVerifyFail(microPayMsg.getOrderId());
                logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl支付返回处理结果：国付宝订单号【"
                        + microPayMsg.getOrderId() + "】验签失败，bis_bank_main_order表更新失败状态");
            }

        } catch (GopayException e) {
            logger.error("MicroPayInteractServiceImpl dealOrderAfterPay gopayException: ", e);
        } catch (Exception e) {
            logger.error("MicroPayInteractServiceImpl dealOrderAfterPay exception: ", e);
        }

    }

    /**
     * 冲正订单--同步处理操作
     * 
     * @param microPayMsg
     * @param result
     * @author w_jiqing
     */
    private Result dealOrderAfterReverse(MicroPayBaseMessage microPayMsg, Result revResult) throws GopayException {

        Result result = new Result(false);

        try {
            if (!revResult.isSuccess()) {// 处理失败
                logger.error(
                        "MicroPayInteractServiceImpl dealOrderAfterReverse resultCode:" + revResult.getResultCode());
                return result;
            }
            
            Map<String, String> param = new HashMap<String, String>();
            // 冲正订单
            BankOrder bankOrder = bankOrderManager.getBankOrderById(microPayMsg.getBankOrderId());

            // 原支付订单
            BankOrder oriBankOrder = bankOrderManager.getBankOrderById(microPayMsg.getCzOriBankOrderId());
            if (bankOrder == null || oriBankOrder == null) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041);
            }
            param = (Map<String, String>) revResult.getModel("isNotifyCashier");
            logger.error(
                    "MicroPayInteractServiceImpl reverse resMsg: " + ToStringBuilder.reflectionToString(microPayMsg));
            if ((Boolean) revResult.getDefaultModel()) {
                if (revResult.isOrderStatus()) {
                    // 冲正成功处理
                    String amt = (String) param.get("amt"); // 银行返回交易金额
                    if (bankOrder.getSendBankAmt() != null
                            && bankOrder.getSendBankAmt().compareTo(new BigDecimal(amt)) != 0) {
                        // 银行返回金额与平台上送金额不符
                        bankOrderManager.updateAmountError(param.get("orderId"));
                        logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 冲正返回处理结果：国付宝订单号【"
                                + param.get("orderId") + "】金额比对异常");
                        SendSmsUtils.sendSmsErr(smsConfig.get("switch"), smsConfig.get("mobile"),
                                "注意!!!冲正订单金额不一致,银行:" + microPayMsg.getOutStlmCd() + "orderId:" + param.get("orderId"));
                        return result;
                    }
                    bankOrderManager.updateBackSuccess(param.get("orderId"));
                    logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 冲正返回处理结果：国付宝订单号【"
                            + param.get("orderId") + "】冲正成功，bis_bank_main_order表更新成功状态");

//                    oriBankOrder.setOrderStatus(BankOrderStatus.FAIL);
//                    bankOrderManager.updateFail(oriBankOrder);
//                    logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 冲正返回处理结果：国付宝订单号【"
//                            + oriBankOrder.getOrderId() + "】冲正成功，bis_bank_main_order表原支付订单更新失败状态");
                    if (microPayMsg.isOrderStatusMark()) {
                        // 支付成功并且冲正成功的订单需要通知收银台
                        param.put("sign", signRes(param));
                        logger.error("bis reverse notify cashier: " + param);
                        /*notifyCashier.submit(param);*/ //生产优化10期 lx 2017-9-30 16:23:37
                        cashierBgNotifyRemoteService.callBgNotify(param);
                    }
                    result.setSuccess(true);
                    result.setModel("flag", true);
                } else {
                    // 冲正非成功处理
                    String amt = (String) param.get("amt"); // 银行返回交易金额
                    if (bankOrder.getSendBankAmt() != null
                            && bankOrder.getSendBankAmt().compareTo(new BigDecimal(amt)) != 0) {
                        // 银行返回金额与平台上送金额不符
                        bankOrderManager.updateAmountError(param.get("orderId"));
                        logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 冲正返回处理结果：国付宝订单号【"
                                + param.get("orderId") + "】金额比对异常");
                        SendSmsUtils.sendSmsErr(smsConfig.get("switch"), smsConfig.get("mobile"),
                                "注意!!!冲正订单金额不一致,银行:" + microPayMsg.getOutStlmCd() + "orderId:" + param.get("orderId"));
                        return result;
                    }
                    bankOrder.setOrderStatus(BankOrderStatus.ORDER_FAIL);
                    bankOrderManager.updateBankOrder(bankOrder);
                    logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl 支付返回处理结果：国付宝订单号【"
                            + microPayMsg.getOrderId() + "】验签成功订单冲正失败");
                    if (microPayMsg.isOrderStatusMark()) {
                        // 支付成功并且冲正成功的订单需要通知收银台
                        param.put("sign", signRes(param));
                        logger.error("bis reverse notify cashier: " + param);
                        /*notifyCashier.submit(param);*/ //生产优化10期 lx 2017-9-30 16:23:37
                        cashierBgNotifyRemoteService.callBgNotify(param);
                    }
                    result.setSuccess(true);
                    result.setModel("flag", false);
                }
            } else {
                bankOrderManager.updateBackVerifyFail(microPayMsg.getOrderId());
                logger.error(microPayMsg.getOutStlmCd() + " MicroPayInteractServiceImpl冲正返回处理结果：国付宝订单号【"
                        + microPayMsg.getOrderId() + "】验签失败，bis_bank_main_order表更新失败状态");
            }
        } catch (GopayException e) {
            logger.error("MicroPayInteractServiceImpl dealOrderAfterPay gopayException: ", e);
        } catch (Exception e) {
            logger.error("MicroPayInteractServiceImpl dealOrderAfterPay exception: ", e);
        }
        return result;

    }
    
    @Override
    public Result reverseQuery(BaseMessage msg) throws GopayException {
        logger.info("------------MicroPayInteractServiceImpl reverseQuery start-------------");
        long beginTime = System.currentTimeMillis();
        MicroPayBaseMessage base = (MicroPayBaseMessage) msg;
        logger.error(
                "MicroPayInteractServiceImpl 小额免密支付reverseQuery查询处理base对象：" + ToStringBuilder.reflectionToString(base));
        Result result = new Result();
        try {
            /**
             * 获取原支付订单信息
             */
            CpsGenMainOrder oriMainOrder = mainOrderQuery.get(base.getCzOriOrderId());
            /**
             * 获取原支付信息
             */
            BankOrder oirBankOrder =bankOrderService.getBankOrderById(base.getCzOriBankOrderId());
            /**
             * 平台外部清算机构代码
             */
            String outStlmCd = InitialSpringBeanName.getOutStlmCd(base.getBankIntrChann().value,
                    oirBankOrder.getBankBizProdCode(), base.getBank());
            base.setOutStlmCd(outStlmCd);
            base.setAmount(oriMainOrder.getTotalOrderAmt());
            base.setCustomerID(oriMainOrder.getMerId());
            /**
             * 获取bean
             */
            String beanName = getBeanName(oriMainOrder, outStlmCd, base.getBankIntrChann().value);

            MicroPayInteractRemoteService microPayService = (MicroPayInteractRemoteService) SpringContextUtil
                    .getBean(beanName);
            if (!BisPayCheckUtils.checkExternalOrderID(base.getOrderId())) {
                // 根据银行业务产品代码、通道代码、银行代码获取通道配置信息
                BaseBisBankExtConfig bankConfig = bisBankExtConfigManager.findExtConfigByBankChannelAndBankBusProd(
                        BisBankBusinessProd.get(oirBankOrder.getBankBizProdCode()), base.getBankIntrChann(), base.getBank());
                /**
				 * 根据银行订单号查询订单扩展表是否存在记录，存在记录获取支付使用的商户号和商户密钥
				 */
				getBisBankOrderExt(oirBankOrder.getOutOrderId(),bankConfig);
                // 设置一级私钥路径
                base.setPrivateKeyPath(bankConfig.getIntrMerPravkeyPath());
                // 设置一级私钥密码
                base.setPrivatePwd(bankConfig.getIntrMerPravkeyPwd());
                // 设置二级私钥路径
                base.setPrivateKeyPath2nd(bankConfig.getIntrMer2ndPravkeyPath());
                // 设置二级私钥密码
                base.setPrivatePwd2nd(bankConfig.getIntrMer2ndPravkeyPwd());
                // 设置公钥路径
                base.setPublicKeyPath(bankConfig.getIntrBankPubkeyPath());
                // 设置商户号
                base.setMerID(bankConfig.getIntrMernum1());
                // 设置二级商户号
                base.setMerID2nd(bankConfig.getIntrMernum2());
                // 设置结算账户网点联行号
                base.setBranchCode(bankConfig.getBranchCode());
                // 设置银行查询地址
                base.setQueryUrl(bankConfig.getQueryUrl());
                base.setPayUrl(bankConfig.getPayUrl());
            }
            /**
             * 调用查询 方法
             */
            result = microPayService.reverseQuery(base);
            logger.error("MicroPayInteractServiceImpl 小额免密支付 冲正查询返回base对象：" + ToStringBuilder.reflectionToString(result));
        } catch (GopayException e) {
            logger.error("MicroPayInteractServiceImpl reverseQuery error: ", e);
            result.setResultCode(e.getErrCode());
            result.setSuccess(false);
        } catch (Exception e) {
            logger.error("MicroPayInteractServiceImpl reverseQuery error: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
        }
        long endTime = System.currentTimeMillis();
        logger.info("------ MicroPayInteractServiceImpl reverseQuery end，耗时(ms):" + (endTime - beginTime));
        return result;
    }

    @Override
    public Result orderQuery(BaseMessage msg) throws GopayException {

        logger.info("------------MicroPayInteractServiceImpl orderQuery start-------------");
        long beginTime = System.currentTimeMillis();
        MicroPayBaseMessage base = (MicroPayBaseMessage) msg;
        logger.error(
                "MicroPayInteractServiceImpl 小额免密支付orderQuery查询处理base对象：" + ToStringBuilder.reflectionToString(base));
        Result result = new Result();
        try {
            /**
             * 获取订单信息
             */
            CpsGenMainOrder mainOrder = mainOrderQuery.get(base.getOrderId());
            /**
             * 平台外部清算机构代码
             */
            String outStlmCd = InitialSpringBeanName.getOutStlmCd(base.getBankIntrChann().value,
                    base.getBankBusProd().value, base.getBank());
            base.setOutStlmCd(outStlmCd);
            base.setAmount(mainOrder.getTotalOrderAmt());
            base.setCustomerID(mainOrder.getMerId());
            /**
             * 获取bean
             */
            String beanName = getBeanName(mainOrder, outStlmCd, base.getBankIntrChann().value);

            MicroPayInteractRemoteService microPayService = (MicroPayInteractRemoteService) SpringContextUtil
                    .getBean(beanName);
            if (!BisPayCheckUtils.checkExternalOrderID(base.getOrderId())) {
                // 根据银行业务产品代码、通道代码、银行代码获取通道配置信息
                BaseBisBankExtConfig bankConfig = bisBankExtConfigManager.findExtConfigByBankChannelAndBankBusProd(
                        base.getBankBusProd(), base.getBankIntrChann(), base.getBank());
                /**
				 * 根据银行订单号查询订单扩展表是否存在记录，存在记录获取支付使用的商户号和商户密钥
				 */
				getBisBankOrderExt(base.getBankOrderId(),bankConfig);
                // 设置一级私钥路径
                base.setPrivateKeyPath(bankConfig.getIntrMerPravkeyPath());
                // 设置一级私钥密码
                base.setPrivatePwd(bankConfig.getIntrMerPravkeyPwd());
                // 设置二级私钥路径
                base.setPrivateKeyPath2nd(bankConfig.getIntrMer2ndPravkeyPath());
                // 设置二级私钥密码
                base.setPrivatePwd2nd(bankConfig.getIntrMer2ndPravkeyPwd());
                // 设置公钥路径
                base.setPublicKeyPath(bankConfig.getIntrBankPubkeyPath());
                // 设置商户号
                base.setMerID(bankConfig.getIntrMernum1());
                // 设置二级商户号
                base.setMerID2nd(bankConfig.getIntrMernum2());
                // 设置结算账户网点联行号
                base.setBranchCode(bankConfig.getBranchCode());
                // 设置银行查询地址
                base.setQueryUrl(bankConfig.getQueryUrl());
                base.setPayUrl(bankConfig.getPayUrl());
            }
            /**
             * 调用查询 方法
             */
            result = microPayService.orderQuery(base);
            logger.error("MicroPayInteractServiceImpl 小额免密支付查询返回base对象：" + ToStringBuilder.reflectionToString(result));
        } catch (GopayException e) {
            logger.error("MicroPayInteractServiceImpl orderQuery error: ", e);
            result.setResultCode(e.getErrCode());
            result.setSuccess(false);
        } catch (Exception e) {
            logger.error("MicroPayInteractServiceImpl orderQuery error: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
        }
        long endTime = System.currentTimeMillis();
        logger.info("------ MicroPayInteractServiceImpl orderQuery end，耗时(ms):" + (endTime - beginTime));
        return result;
    }

    @Override
    public Result refund(BaseMessage msg) throws GopayException {
        logger.error("MicroPayInteractServiceImpl银行退款处理base对象：" + ToStringBuilder.reflectionToString(msg));
        MicroPayBaseMessage base = new MicroPayBaseMessage();
        BeanUtils.copyProperties(msg, base);
        Result result = new Result();
        try {
            /**
             * 获取原支付订单信息与银行信息
             */
            CpsGenMainOrder mainOrder = mainOrderQuery.get(msg.getTkOriOrderId());
            /**
             * 获取原支付银行订单
             */
            List<BankOrder> bankOrders = bankOrderService.getBankOrdersByGopayOrderId(msg.getTkOriOrderId());
            BankOrder bankOrder = bankOrders.get(0);
            logger.error("退款发起  bankorder------" + ToStringBuilder.reflectionToString(bankOrder));
            if (!isSendTkOrder(bankOrder.getOutOrderId())) {
                /**
                 * 已存在处理中退款交易
                 */
                result.setResultCode(ProcCodeConstants.PROC_CODE_100E6089);
                result.setSuccess(false);
                return result;
            }
            BisBankInterfaceChannel channel = BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode());
            BisBankBusinessProd prod = BisBankBusinessProd.get(bankOrder.getBankBizProdCode());

            /**
             * 获取SPRING加载的BeanName
             */
            String outStlmId = InitialSpringBeanName.getOutStlmCd(channel.value, prod.value, bankOrder.getBankCode());
            base.setOutStlmCd(outStlmId);
            /**
             * 原支付订单总金额
             */
            base.setTkOriAmount(mainOrder.getTotalOrderAmt());
            String beanName = getBeanName(mainOrder, outStlmId, channel.value);
            MicroPayInteractRemoteService microPayService = (MicroPayInteractRemoteService) SpringContextUtil
                    .getBean(beanName);
            base.setBankOrderId(modifyOrderId(base.getOrderId(), channel.value));
            base.setTkOriBankOrderId(bankOrder.getOutOrderId());
            base.setBankBusProd(BisBankBusinessProd._12); // 退款
            base.setBankIntrChann(channel);
            base.setBank(bankOrder.getBankCode());
            base.setBankOrderType(BankOrderType.GOPAY_BIS_ORDER);// 订单类型：新平台订单
            base.setCustomerID(mainOrder.getMerId());
            if (!BisPayCheckUtils.checkExternalOrderID(base.getOrderId())) {
                // 根据银行业务产品代码、通道代码、银行代码获取通道配置信息
                BaseBisBankExtConfig bankConfig = bisBankExtConfigManager.findExtConfigByBankChannelAndBankBusProd(prod,
                        channel, base.getBank());
                /**
				 * 根据银行订单号查询订单扩展表是否存在记录，存在记录获取支付使用的商户号和商户密钥
				 */
				getBisBankOrderExt(bankOrder.getOutOrderId(),bankConfig);
                // 设置一级私钥路径
                base.setPrivateKeyPath(bankConfig.getIntrMerPravkeyPath());
                // 设置一级私钥密码
                base.setPrivatePwd(bankConfig.getIntrMerPravkeyPwd());
                // 设置二级私钥路径
                base.setPrivateKeyPath2nd(bankConfig.getIntrMer2ndPravkeyPath());
                // 设置二级私钥密码
                base.setPrivatePwd2nd(bankConfig.getIntrMer2ndPravkeyPwd());
                // 设置公钥路径
                base.setPublicKeyPath(bankConfig.getIntrBankPubkeyPath());
                // 设置商户号
                base.setMerID(bankConfig.getIntrMernum1());
                // 设置二级商户号
                base.setMerID2nd(bankConfig.getIntrMernum2());
                // 设置结算账户网点联行号
                base.setBranchCode(bankConfig.getBranchCode());
                // 设置银行查询地址
                base.setQueryUrl(bankConfig.getQueryUrl());
                // 设置银行支付地址
                base.setPayUrl(bankConfig.getPayUrl());
            }

            // 退款
            result = microPayService.refund(base);

            logger.error("MicroPayInteractServiceImpl银行退款返回base对象：" + ToStringBuilder.reflectionToString(result));
        } catch (GopayException e) {
            logger.error("MicroPayInteractServiceImpl refund error: ", e);
            result.setResultCode(e.getErrCode());
            result.setSuccess(false);
        } catch (Exception e) {
            logger.error("MicroPayInteractServiceImpl refund error: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
        }
        return result;
    }

    @Override
    public Result refundQuery(BaseMessage msg) throws GopayException {
        Result result = new Result();
        MicroPayBaseMessage base = (MicroPayBaseMessage) msg;
        try {
            logger.error("MicroPayInteractServiceImpl退款查询处理base对象：" + ToStringBuilder.reflectionToString(base));
            /**
             * 获取原支付银行订单
             */
            BankOrder bankOrder = bankOrderService.getBankOrderById(msg.getTkOriBankOrderId());
            /**
             * 获取原支付订单
             */
            CpsGenMainOrder mainOrder = mainOrderQuery.get(bankOrder.getOrderId());
            BisBankInterfaceChannel channel = BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode());
            BisBankBusinessProd prod = BisBankBusinessProd.get(bankOrder.getBankBizProdCode());
            /**
             * 获取SPRING加载的BeanName
             */
            String outStlmId = InitialSpringBeanName.getOutStlmCd(channel.value, prod.value, base.getBank());
            base.setOutStlmCd(outStlmId);
            // base.setAmount(mainOrder.getTotalOrderAmt());
            base.setTkOriBankOrderId(bankOrder.getOutOrderId());
            base.setCustomerID(mainOrder.getMerId());
            String beanName = getBeanName(mainOrder, outStlmId, channel.value);
            MicroPayInteractRemoteService microPayService = (MicroPayInteractRemoteService) SpringContextUtil
                    .getBean(beanName);

            if (!BisPayCheckUtils.checkExternalOrderID(base.getOrderId())) {
                // 根据银行业务产品代码、通道代码、银行代码获取通道配置信息
                BaseBisBankExtConfig bankConfig = bisBankExtConfigManager.findExtConfigByBankChannelAndBankBusProd(prod,
                        channel, base.getBank());
                /**
				 * 根据银行订单号查询订单扩展表是否存在记录，存在记录获取支付使用的商户号和商户密钥
				 */
				getBisBankOrderExt(bankOrder.getOutOrderId(),bankConfig);
                // 设置一级私钥路径
                base.setPrivateKeyPath(bankConfig.getIntrMerPravkeyPath());
                // 设置一级私钥密码
                base.setPrivatePwd(bankConfig.getIntrMerPravkeyPwd());
                // 设置二级私钥路径
                base.setPrivateKeyPath2nd(bankConfig.getIntrMer2ndPravkeyPath());
                // 设置二级私钥密码
                base.setPrivatePwd2nd(bankConfig.getIntrMer2ndPravkeyPwd());
                // 设置公钥路径
                base.setPublicKeyPath(bankConfig.getIntrBankPubkeyPath());
                // 设置商户号
                base.setMerID(bankConfig.getIntrMernum1());
                // 设置二级商户号
                base.setMerID2nd(bankConfig.getIntrMernum2());
                // 设置结算账户网点联行号
                base.setBranchCode(bankConfig.getBranchCode());
                // 设置银行查询地址
                base.setQueryUrl(bankConfig.getQueryUrl());
                // 设置银行支付地址
                base.setPayUrl(bankConfig.getPayUrl());
            }
            // 查询
            result = microPayService.refundQuery(base);
            logger.error("MicroPayInteractServiceImpl退款查询返回base对象：" + ToStringBuilder.reflectionToString(result));
        } catch (GopayException e) {
            logger.error("MicroPayInteractServiceImpl refundQuery error: ", e);
            result.setResultCode(e.getErrCode());
            result.setSuccess(false);
        } catch (Exception e) {
            logger.error("MicroPayInteractServiceImpl refundQuery error: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
        }
        return result;

    }

    @Override
    public Result reverse(BaseMessage base) throws GopayException {
        logger.error("MicroPayInteractServiceImpl冲正处理base对象：" + ToStringBuilder.reflectionToString(base));
        Result result = new Result();
        try {
            MicroPayBaseMessage microPayMsg = new MicroPayBaseMessage();
            BeanUtils.copyProperties(base, microPayMsg);

            // 获取原支付订单信息与银行信息
            CpsGenMainOrder mainOrder = mainOrderQuery.get(microPayMsg.getCzOriOrderId());
            // 获取原支付银行订单
            List<BankOrder> bankOrders = bankOrderService.getBankOrdersByGopayOrderId(microPayMsg.getCzOriOrderId());
            if (bankOrders == null || bankOrders.size()<= 0) {
                result.setResultCode(ProcCodeConstants.PROC_CODE_100E5012);// 原交易不存在
                result.setSuccess(false);
                return result;
            }
            /**
             * 校验银行订单不能为多条,此处以后修改
             */
            List<BankOrder> czBankOrders = bankOrderService.getBankOrdersByGopayOrderId(microPayMsg.getOrderId());
            if (czBankOrders != null && czBankOrders.size() > 0) {
                result.setResultCode(ProcCodeConstants.PROC_CODE_100E5015);// 已存在相同的订单
                result.setSuccess(false);
                return result;
            }

            BankOrder bankOrder = bankOrders.get(0);
            logger.error("冲正发起  bankorder------" + ToStringBuilder.reflectionToString(bankOrder));
            if (!isSendCZOrder(bankOrder.getOutOrderId())) {
                // 已存在冲正成功的订单
                result.setResultCode(ProcCodeConstants.PROC_CODE_100E1180);
                result.setSuccess(false);
                logger.error("watch--after isSendCZOrder--" + bankOrder.getOrderId());
                return result;
            }
            BisBankInterfaceChannel channel = BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode());
            BisBankBusinessProd prod = BisBankBusinessProd.get(bankOrder.getBankBizProdCode());
            String outStlmId = InitialSpringBeanName.getOutStlmCd(channel.value, prod.value, bankOrder.getBankCode());
            microPayMsg.setOutStlmCd(outStlmId);
            String beanName = getBeanName(mainOrder, outStlmId, channel.value);
            MicroPayInteractRemoteService microPayService = (MicroPayInteractRemoteService) SpringContextUtil
                    .getBean(beanName);
            if (!BisPayCheckUtils.checkExternalOrderID(base.getOrderId())) {
                // 根据银行业务产品代码、通道代码、银行代码获取通道配置信息
                BaseBisBankExtConfig bankConfig = bisBankExtConfigManager.findExtConfigByBankChannelAndBankBusProd(prod, channel, outStlmId);
                /**
				 * 根据银行订单号查询订单扩展表是否存在记录，存在记录获取支付使用的商户号和商户密钥
				 */
				getBisBankOrderExt(bankOrder.getOutOrderId(),bankConfig);
                // 设置一级私钥路径
                microPayMsg.setPrivateKeyPath(bankConfig.getIntrMerPravkeyPath());
                // 设置一级私钥密码
                microPayMsg.setPrivatePwd(bankConfig.getIntrMerPravkeyPwd());
                // 设置二级私钥路径
                microPayMsg.setPrivateKeyPath2nd(bankConfig.getIntrMer2ndPravkeyPath());
                // 设置二级私钥密码
                microPayMsg.setPrivatePwd2nd(bankConfig.getIntrMer2ndPravkeyPwd());
                // 设置公钥路径
                microPayMsg.setPublicKeyPath(bankConfig.getIntrBankPubkeyPath());
                // 设置商户号
                microPayMsg.setMerID(bankConfig.getIntrMernum1());
                // 设置二级商户号
                microPayMsg.setMerID2nd(bankConfig.getIntrMernum2());
                // 设置结算账户网点联行号
                microPayMsg.setBranchCode(bankConfig.getBranchCode());
                // 设置银行支付地址
                microPayMsg.setPayUrl(bankConfig.getPayUrl());
                // 设置支付后台通知地址
                microPayMsg.setPayRuturnUrl(bankConfig.getPayRuturnUrl());
                // 设置银行查询地址
                microPayMsg.setQueryUrl(bankConfig.getQueryUrl());
            }
            microPayMsg.setBankOrderId(microPayMsg.getOrderId());
            microPayMsg.setCzOriBankOrderId(bankOrder.getOutOrderId());
            microPayMsg.setBankBusProd(BisBankBusinessProd._26); // 冲正
            microPayMsg.setBankIntrChann(channel);
            microPayMsg.setBank(bankOrder.getBankCode());
            microPayMsg.setAmount(bankOrder.getSendBankAmt());
            microPayMsg.setBankOrderType(BankOrderType.GOPAY_BIS_ORDER);// 订单类型：新平台订单
            microPayMsg.setCustomerID(mainOrder.getMerId());
            
            // 保存退款订单
            bankOrderService.addBankOrder(microPayMsg);

            Result revResult = microPayService.reverse(microPayMsg);         

            // 中信小额免密支付同步返回处理结果
            if (BisBankBusinessProd._26.value.equals(microPayMsg.getBankBusProd().value)) {

                result = dealOrderAfterReverse(microPayMsg, revResult);
            }
            
            result.setResultCode(ProcCodeConstants.PROC_CODE_100S1000);
            
            logger.error("MicroPayInteractServiceImpl 小额免密支付冲正返回base对象：" + ToStringBuilder.reflectionToString(result));
        } catch (GopayException e) {
            logger.error("BankInteractServiceImpl refund error: ", e);
            result.setResultCode(e.getErrCode());
            result.setSuccess(false);
        } catch (Exception e) {
            logger.error("BankInteractServiceImpl refund error: ", e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 
     * 功能描述：校验请求参数
     *
     * @param request
     *            请求对象
     * @throws GopayException
     * 
     * @author 宣广海
     *
     * @since 2016年8月8日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private void checkRequest(MicroPayRequest request) throws GopayException {

        String orderId = request.getOrderId();// 订单号
        String mchCreateIp = request.getMchCreateIp();// 终端IP
        String bank = request.getMicroType();// 银行code
        String bankBusProd = request.getBankBusProd().value;// 业务产品
        String goodsBody = request.getGoodsBody();// 产品描述
        if (StringUtils.isBlank(bankBusProd)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E7014);
        }
        /**
         * 小额免密支付
         */
        if (BisBankBusinessProd._25.value.equals(bankBusProd)) {
            if (StringUtils.isBlank(request.getAuthCode())) {
                // 新增错误码
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E1183);
            }
        }
        if (StringUtils.isBlank(orderId)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E1089);
        }
        if (StringUtils.isBlank(mchCreateIp)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E1016);
        }
        if (StringUtils.isBlank(bank)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E1135);
        }
        if (StringUtils.isBlank(goodsBody)) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E1083);
        }
    }

    /**
     * 
     * 功能描述：校验银行业务产品是否支持该通道
     *
     * @param config
     * @param bankBusProd
     * @throws GopayException
     * 
     * @author 宣广海
     *
     * @since 2016年8月8日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private void checkBankBussProdAndIntrChan(BaseBisBankExtConfig config, String bankBusProd) throws GopayException {
        if (null == config) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E7021);
        }
        String intrChann = config.getChCode();// 接口通道
        bankIntrChannConfService.checkBankBussProdAndIntrChan(intrChann, bankBusProd);
    }

    /**
     * 
     * 功能描述：校验银行通道信息是否支持支付等交易
     *
     * @param config
     * @param outTranCode
     * @throws GopayException
     * 
     * @author 宣广海
     *
     * @since 2016年8月8日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private void checkBankIntrChan(BaseBisBankConfig config, OutStlmTranCode outTranCode) throws GopayException {
        bankIntrChannConfService.checkBankIntrChan(config, outTranCode);
    }

    private static String modifyOrderId(String orderId, String chann) {
        // 中信
        if ("15".equals(chann)) {
            orderId = "WF" + orderId.substring(2);
        }
        // 民生扫码
        if ("17".equals(chann)) {
            orderId = "MS" + orderId.substring(2);
        }
        // 兴业
        if ("16".equals(chann)) {
            orderId = "XY" + orderId.substring(2);
        }
        if ("25".equals(chann)) {
            orderId = "PA" + orderId.substring(2);
        }
        // 浦发
        if ("28".equals(chann)) {
            orderId = "SP" + orderId.substring(2);
        }
        return orderId;
    }

    /**
     * 获取SPRING加载的BeanName
     * 
     * <pre>
     * BeanName规范:银行编码-交易类型，如TBANK-B2B
     * </pre>
     * 
     * @param mainOrder
     *            订单信息
     * @param bankInfo
     *            银行信息
     * @return
     * @throws GopayException
     */
    private String getBeanName(CpsGenMainOrder mainOrder, String outStlmId, String inChann) throws GopayException {
        String beanSuffix = TradeType.getOrderTrandType(mainOrder.getPayChannel());
        if (StringUtils.equalsIgnoreCase(outStlmId, "WECHAT")
                && StringUtils.equals(inChann, BisBankInterfaceChannel._16.value)) {
            String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_CIB;
            return beanName;
        }
        // add by jxj 添加对民生扫码支付的判断
        if (StringUtils.equalsIgnoreCase(outStlmId, "WECHAT")
                && StringUtils.equals(inChann, BisBankInterfaceChannel._17.value)) {
            String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_CMBC;
            return beanName;
        }
        if (StringUtils.equalsIgnoreCase(outStlmId, "ALIPAY")
                && StringUtils.equals(inChann, BisBankInterfaceChannel._17.value)) {
            String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_CMBC;
            return beanName;
        }
        // 新增小额免密支付
        if (StringUtils.equalsIgnoreCase(outStlmId, "WECHAT")
                && StringUtils.equals(inChann, BisBankInterfaceChannel._15.value)) {
            String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_CITIC;
            return beanName;
        }
        if (StringUtils.equalsIgnoreCase(outStlmId, "ALIPAY")
                && StringUtils.equals(inChann, BisBankInterfaceChannel._15.value)) {
            String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_CITIC;
            return beanName;
        }
        if (StringUtils.equalsIgnoreCase(outStlmId, "WECHAT")
                && StringUtils.equals(inChann, BisBankInterfaceChannel._25.value)) {
            String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_PAB;
            return beanName;
        }
        if (StringUtils.equalsIgnoreCase(outStlmId, "ALIPAY")
                && StringUtils.equals(inChann, BisBankInterfaceChannel._25.value)) {
            String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_PAB;
            return beanName;
        }
        // 新增spdb条码支付
        if (StringUtils.equalsIgnoreCase(outStlmId, "WECHAT")
				&& StringUtils.equals(inChann, BisBankInterfaceChannel._28.value)){
			String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_SPDB;
			return beanName;
		}
        if (StringUtils.equalsIgnoreCase(outStlmId, "ALIPAY")
				&& StringUtils.equals(inChann, BisBankInterfaceChannel._28.value)){
			String beanName = outStlmId + "-" + beanSuffix + "-" + BankConstants.BANK_LOGO_SPDB;
			return beanName;
		}
        String beanName = outStlmId + "-" + beanSuffix;
        return beanName;
    }

    /**
     * 是否为自动路由
     * 
     * @param merId
     * @return
     */
    private boolean isRouteOrWhiteList(String merId) {
        // 是否为白名单商户
        boolean isWhite = bisBankWhiteListMerchantsService.isWhiteListMerchant(merId);
        if (AUTO_ROUTING.equals(bisConfig.get("GOPAY.AUTO.ROUTING")) || isWhite) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 
     * 功能描述：是否已经发起退款交易
     *
     * @param oriOutOrderId
     * @return
     * 
     * @author 宣广海
     *
     * @since 2016年10月17日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private boolean isSendTkOrder(String oriOutOrderId) {
        boolean flag = true;
        // 根据原交易银行订单号获取退款订单
        List<BankOrder> tkBankOrders = bankOrderService.getBankOrdersByOriBankOrderId(oriOutOrderId);
        if (tkBankOrders != null && tkBankOrders.size() > 0) {
            // 同一支付订单下多笔退款时候, 前一笔退款状态为成功或者失败的情况下, 才允许做下一笔退款
            for (int i = 0; i < tkBankOrders.size(); i++) {
                String orderStatus = tkBankOrders.get(i).getOrderStatus();
                if (BankOrderStatus.PROCESS.equals(orderStatus)) {
                    // 已存在处理中退款交易
                    logger.error("MicroPayInteractServiceImpl refund isSendTkOrder: 已存在处理中退款交易 "
                            + tkBankOrders.get(i).getOrderId());
                    flag = false;
                    break;
                }
            }
        }
        return flag;
    }

    private boolean isSendCZOrder(String oriOutOrderId) {
        boolean flag = true;
        // 根据原交易银行订单号获取冲正订单
        List<BankOrder> czBankOrders = bankOrderService.getBankOrdersByOriBankOrderId(oriOutOrderId);
        if (czBankOrders != null && czBankOrders.size() > 0) {
            // 同一支付订单下多笔冲正时候, 有一笔冲正成功的订单。不允许再次发起
            for (int i = 0; i < czBankOrders.size(); i++) {
                String orderStatus = czBankOrders.get(i).getOrderStatus();
                if (BankOrderStatus.BANK_CALL_SUCCESS.equals(orderStatus) || BankOrderStatus.AUTO_CHECK_SUCCESS.equals(orderStatus)||BankOrderStatus.CHECK_SUCCESS.equals(orderStatus)) {
                    // 已存在冲正成功交易
                    logger.error("MicroPayInteractServiceImpl reverse isSendCZOrder: 已存在冲正成功的交易 "
                            + czBankOrders.get(i).getOrderId());
                    flag = false;
                    break;
                }
            }
        }
        return flag;
    }

    /**
     * 通知cashier签名
     * 
     * @param res
     * @return
     */
    public String signRes(Map<String, String> res) {
        StringBuffer sign = new StringBuffer();
        String orderId = (String) res.get("orderId");
        String amt = (String) res.get("amt");
        String retCode = (String) res.get("retCode");
        String retMsg = (String) res.get("retMsg")==null?"":(String) res.get("retMsg");
        String payStatus = (String) res.get("payStatus");
        String notifyNum = (String) res.get("notifyNum");
        String cardType = (String) res.get("cardType");
        sign.append(orderId).append("|");
        sign.append(amt).append("|");
        sign.append(retCode).append("|");
        sign.append(retMsg).append("|");
        sign.append(payStatus).append("|");
        sign.append(notifyNum).append("|");
        sign.append(cardType);
        logger.error("micro bis 通知cashier签名明文: " + sign.toString());
        try {
            return RSAEncoderUtil.sign(sign.toString());
        } catch (Exception e) {
            logger.error("micro bis 通知cashier签名异常： ", e);
        }
        return "";
    }

    private BaseBisBankExtConfig getBisBankOrderExt(String bankOrderId,BaseBisBankExtConfig bankConfig) throws GopayException {
		if (bankOrderId == null || "".equals(bankOrderId)) {
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041);
		}
		BankOrderExt bankOrderExt =bankOrderManager.getBankOrderExtById(bankOrderId);
		if(null!=bankOrderExt){
			logger.error("-----------查询一户一码特有商户号为：---------------" + bankOrderExt.getMerchantId());
			bankConfig.setIntrMernum1(bankOrderExt.getMerchantId());
			bankConfig.setIntrMerPravkeyPath(bankOrderExt.getMerchantKey());
		}
		return bankConfig;
	}

}
